home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_005 / timer / timer.c < prev   
C/C++ Source or Header  |  1992-05-06  |  11KB  |  408 lines

  1. /*
  2.  *
  3.  *    DISCLAIMER:
  4.  *
  5.  *    This program is provided as a service to the programmer
  6.  *    community to demonstrate one or more features of the Amiga
  7.  *    personal computer.  These code samples may be freely used
  8.  *    for commercial or noncommercial purposes.
  9.  * 
  10.  *     Commodore Electronics, Ltd ("Commodore") makes no
  11.  *    warranties, either expressed or implied, with respect
  12.  *    to the program described herein, its quality, performance,
  13.  *    merchantability, or fitness for any particular purpose.
  14.  *    This program is provided "as is" and the entire risk
  15.  *    as to its quality and performance is with the user.
  16.  *    Should the program prove defective following its
  17.  *    purchase, the user (and not the creator of the program,
  18.  *    Commodore, their distributors or their retailers)
  19.  *    assumes the entire cost of all necessary damages.  In 
  20.  *    no event will Commodore be liable for direct, indirect,
  21.  *    incidental or consequential damages resulting from any
  22.  *    defect in the program even if it has been advised of the 
  23.  *    possibility of such damages.  Some laws do not allow
  24.  *    the exclusion or limitation of implied warranties or
  25.  *    liabilities for incidental or consequential damages,
  26.  *    so the above limitation or exclusion may not apply.
  27.  *
  28.  */
  29.  
  30. /* SIMPLE TIMER EXAMPLE PROGRAM: 
  31.  *
  32.  * Includes dynamic allocation of data structures needed to communicate
  33.  * with the timer device as well as the actual device IO
  34.  *
  35.  * Author:  Rob Peck, 12/1/85 */
  36.  
  37. #include "exec/types.h"
  38. #include "exec/nodes.h"
  39. #include "exec/lists.h"
  40. #include "exec/memory.h"
  41. #include "exec/interrupts.h"
  42. #include "exec/ports.h"
  43. #include "exec/libraries.h"
  44. #include "exec/io.h"
  45. #include "exec/tasks.h"
  46. #include "exec/execbase.h"
  47. #include "exec/devices.h"
  48. #include "devices/timer.h"
  49.  
  50. long TimerBase;        /* to get at the time comparison functions */
  51.  
  52. main()
  53. {
  54.     LONG error;
  55.     LONG days, minutes,seconds;
  56.     struct timeval mytimeval;
  57.     struct timeval oldtimeval;    /* save what system thinks is
  58.                      * the time.... we'll advance it
  59.                      * temporarily 
  60.                      */
  61.     printf("\ntimer test");
  62.  
  63.     TimeDelay(2,0,0);
  64.     printf("\nAfter 2 seconds delay");
  65.  
  66.     TimeDelay(4,0,0);
  67.     printf("\nAfter 4 seconds delay");
  68.  
  69.     TimeDelay(0,500000,0);    /* 500,000 seconds = 1/2 second */
  70.     printf("\nAfter 1/2 second delay");
  71.  
  72.     printf("\n\n");
  73.     error = Execute("date",0,0);    /* normal system startup file 
  74.                      * opens dos.library, so it is
  75.                      * ok in such cases to use dos calls */
  76.  
  77.     GetSysTime(&oldtimeval);
  78.     printf("\nCurrent system time is %ld current seconds", 
  79.         oldtimeval.tv_secs);    
  80.  
  81.     printf("\nSetting a new system time");
  82.  
  83.     days = 1000 + oldtimeval.tv_secs / (24*60*60);
  84.     minutes = (oldtimeval.tv_secs % (24*60*60)) / 60;
  85.     seconds = (oldtimeval.tv_secs % (24*60*60)) % 60;
  86.  
  87.     SetNewTime(days, minutes, seconds);
  88.     /* (if user executes the AmigaDOS DATE command now, he will
  89.      * see that the time has advanced something over 1000 days */
  90.  
  91.     printf("\n\n");
  92.     error = Execute("date",0,0);    /* normal system startup file 
  93.                      * opens dos.library, so it is
  94.                      * ok in such cases to use dos calls */
  95.     GetSysTime(&mytimeval);
  96.     printf("\nCurrent system time is %ld.%06ld", 
  97.         mytimeval.tv_secs,mytimeval.tv_micro);    
  98.  
  99.     GetSysTime(&mytimeval);
  100.     printf("\nCurrent system time is %ld.%06ld", 
  101.         mytimeval.tv_secs,mytimeval.tv_micro);    
  102.  
  103.     GetSysTime(&mytimeval);
  104.     printf("\nCurrent system time is %ld.%06ld", 
  105.         mytimeval.tv_secs,mytimeval.tv_micro);    
  106.  
  107.     /* added the microseconds part to show that time keeps
  108.      * increasing even though you ask many times in a row */
  109.  
  110.     printf("\nResetting to former time");
  111.  
  112.     days = oldtimeval.tv_secs / (24*60*60);
  113.     minutes = (oldtimeval.tv_secs % (24*60*60)) / 60;
  114.     seconds = (oldtimeval.tv_secs % (24*60*60)) % 60;
  115.  
  116.     SetNewTime(days, minutes, seconds);
  117.  
  118.     GetSysTime(&mytimeval);
  119.     printf("\nCurrent system time is %ld.%06ld", 
  120.         mytimeval.tv_secs,mytimeval.tv_micro);    
  121.  
  122.     TimerBase = GetTimerBase();    
  123.         /* just shows how to set up for using 
  124.          * the timer functions, does not demonstrate
  125.          * the functions themselves.  (TimerBase must
  126.          * have a legal value before AddTime, SubTime or CmpTime
  127.          * are performed.
  128.          */
  129. }
  130.  
  131. /* *********************************************************************** */
  132. /*    Timer function - timedelay(seconds,microseconds)
  133.  
  134.     Your task is put to sleep for the specified time interval.
  135.  
  136.     If seconds > 0, then UNIT_VBLANK is used, delay is in multiples of
  137.     60ths of a second.  If seconds < 0, then UNIT_MICROHZ is used for 
  138.     more precision.    
  139.  
  140.     Returns value of 0 if no errors, nonzero (and no task sleeping)
  141.  
  142.     Notice that since this is a multi-tasking system, the delays
  143.     shown here must be considered to be only approximate.
  144.  
  145.     Also note that this function is used primarily to show how
  146.     a timer device is accessed, including the creation of the 
  147.     message port and a message structure (IOStdReq).   Note that
  148.     there is a Delay(interval) function already in the DOS.library.
  149.     (See the DOS developer's manual for details).
  150.  
  151. */
  152. /* *********************************************************************** */
  153.  
  154. extern struct MsgPort *CreatePort();
  155. extern struct IORequest *CreateExtIO();
  156.  
  157. struct timerequest 
  158. *PrepareTimer(precision)
  159. SHORT precision;
  160. {
  161.     /* return a pointer to a time request.  If any problem, return NULL */
  162.  
  163.     int error;
  164.     SHORT whichunit;
  165.  
  166.     struct MsgPort *timerport;
  167.     struct timerequest *timermsg;
  168.     
  169.         timerport = CreatePort(0,0);
  170.         if (timerport == NULL) 
  171.         return(NULL);    /* Error during CreatePort */
  172.  
  173.     timermsg = (struct timerequest *)CreateExtIO(
  174.                     timerport,sizeof(struct timerequest));
  175.     if (timermsg == NULL)
  176.         {
  177.         DeletePort(timerport);
  178.         return(NULL);    /* Error during CreateExtIO */
  179.         }
  180.     
  181.     if(precision)    /* if true, use precision timer  ( under 1 second ) */
  182.         whichunit = UNIT_MICROHZ;
  183.     else
  184.         whichunit = UNIT_VBLANK;
  185.  
  186.     error = OpenDevice(TIMERNAME, whichunit, timermsg, 0);
  187.     if (error != 0)
  188.         {
  189.         DeleteExtIO(timermsg,sizeof(struct timerequest));
  190.         DeletePort(timerport);
  191.         return(NULL);    /* Error during OpenDevice */
  192.         }
  193.     return(timermsg);
  194. }
  195.  
  196. int
  197. GetTimerBase()
  198. {
  199.     int tbase;
  200.     struct timerequest *tr;
  201.     tr = PrepareTimer();
  202.     tbase = (int)tr->tr_node.io_Device;        
  203.     DeleteTimer(tr);
  204.     return(tbase);
  205. }
  206.  
  207. int 
  208. TimeDelay(seconds,microseconds,precision)
  209.         /* more precise timer than AmigaDOS Delay() */
  210. ULONG seconds,microseconds;
  211. int precision;
  212. {
  213.     int precise;
  214.     struct timerequest *tr;
  215.     if(seconds < 0 || precision != 0)
  216.                 /* do delay in terms of microseconds */ 
  217.         precise = TRUE; /* yes, use the precision timer.     */
  218.     else 
  219.         precise = FALSE; /* no, not necessary */
  220.  
  221.     tr = PrepareTimer(precise);
  222.                     /* get a pointer to an initialized
  223.                      * timer request block */
  224.     if(tr == NULL) return(-1);    /* any nonzero return says timedelay
  225.                      * routine didn't work. */
  226.     WaitForTimer(tr,seconds,microseconds);
  227.  
  228.     DeleteTimer(tr);    /* deallocate temporary structures */
  229.     return(0);
  230. }            /* end of timedelay */
  231.  
  232.  
  233. int
  234. WaitForTimer(tr,seconds,microseconds)
  235. ULONG seconds,microseconds;
  236. struct timerequest *tr;
  237. {
  238.     tr->tr_node.io_Command = TR_ADDREQUEST;   /* add a new timer request */
  239.         tr->tr_time.tv_secs =  seconds;            /* seconds */
  240.         tr->tr_time.tv_micro = microseconds;     /* microseconds */
  241.         DoIO( tr );                     /* post request to the timer */
  242.                         /* goes to sleep till done */
  243.     return(0);
  244. }
  245.  
  246. int
  247. SetNewTime(day,min,sec)
  248. LONG day, min,sec;    /* days since 1 Jan 78 plus minutes */
  249. {
  250.         struct timerequest *tr;
  251.         tr = PrepareTimer(TRUE);  /* MUST use Precise timer for this */
  252.         if(tr == 0) return(-1);   /* non zero return says error */ 
  253.  
  254.     tr->tr_node.io_Command = TR_SETSYSTIME;
  255.     tr->tr_time.tv_secs = (24 * 60 * 60 * day) + (60 * min) + sec;
  256.     tr->tr_time.tv_micro = 0;
  257.     DoIO( tr );
  258.  
  259.     DeleteTimer(tr);
  260.     return(0);
  261. }
  262.  
  263.  
  264. int
  265. GetSysTime(tv)
  266. struct timeval *tv;
  267. {
  268.     struct timerequest *tr;
  269.     tr = PrepareTimer(TRUE);    /* MUST use Precise timer for this */
  270.     if(tr == 0) return(-1);        /* non zero return says error */
  271.  
  272.     tr->tr_node.io_Command = TR_GETSYSTIME;
  273.     DoIO( tr );
  274.  
  275.     tv->tv_secs = tr->tr_time.tv_secs;
  276.     tv->tv_micro = tr->tr_time.tv_micro;
  277.  
  278.     DeleteTimer(tr);
  279.     return(0);
  280.  
  281. }
  282.  
  283. int
  284. DeleteTimer(tr)
  285. struct timerequest *tr;
  286. {
  287.     struct MsgPort *tp;
  288.  
  289.     tp = tr->tr_node.io_Message.mn_ReplyPort;
  290.     if(tr != 0)
  291.     {
  292.         CloseDevice(tr);
  293.         DeleteExtIO(tr,sizeof(struct timerequest));
  294.     }
  295.     if(tp != 0)
  296.         DeletePort(tp);
  297.     return(0);        
  298. }
  299.  
  300.  
  301.  
  302. /***********************************************************************
  303. *
  304. *    Exec Support Function -- Extended IO Request
  305. *
  306. ***********************************************************************/
  307.  
  308. extern APTR AllocMem();
  309.  
  310. /****** exec_support/CreateExtIO **************************************
  311. *
  312. *   NAME    
  313. *    CreateExtIO() -- create an Extended IO request
  314. *
  315. *   SYNOPSIS
  316. *    ioReq = CreateExtIO(ioReplyPort,size);   
  317. *
  318. *   FUNCTION
  319. *    Allocates memory for and initializes a new IO request block
  320. *    of a user-specified number of bytes.
  321. *
  322. *   INPUTS
  323. *    ioReplyPort - a pointer to an already initialized
  324. *        message port to be used for this IO request's reply port.
  325. *
  326. *   RESULT
  327. *    Returns a pointer to the new block.  Pointer is of the type
  328. *    struct IORequest.
  329. *
  330. *    0 indicates inability to allocate enough memory for the request block
  331. *    or not enough signals available.
  332. *
  333. *   EXAMPLE
  334. *    struct IORequest *myBlock;
  335. *    if( (myBlock = CreateExtIO(myPort,sizeof(struct IOExtTD)) == NULL)
  336. *        exit(NO_MEM_OR_SIGNALS);
  337. *
  338. *    example used to allocate space for IOExtTD (trackdisk driver
  339. *    IO Request block for extended IO operations).
  340. *
  341. *   SEE ALSO
  342. *    DeleteExtIO
  343. *
  344. ***********************************************************************/
  345.  
  346. struct IORequest *CreateExtIO(ioReplyPort,size)
  347.     struct MsgPort *ioReplyPort;
  348.     LONG size;
  349. {
  350.     struct IORequest *ioReq;
  351.  
  352.     if (ioReplyPort == 0)
  353.     return ((struct IORequest   *) 0);
  354.  
  355.     ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC);
  356.  
  357.     if (ioReq == 0)
  358.     return ((struct IORequest   *) 0);
  359.  
  360.     ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE;
  361.     ioReq -> io_Message.mn_Node.ln_Pri = 0;
  362.  
  363.     ioReq -> io_Message.mn_ReplyPort = ioReplyPort;
  364.  
  365.     return (ioReq);
  366. }
  367.  
  368. /****** exec_support/DeleteExtIO **************************************
  369. *
  370. *   NAME
  371. *    DeleteExtIO() - return memory allocated for extended IO request
  372. *
  373. *   SYNOPSIS
  374. *    DeleteExtIO(ioReq,size);
  375. *
  376. *   FUNCTION
  377. *    See summary line at NAME.  Also frees the signal bit which
  378. *    had been allocated by the call to CreateExtIO.
  379. *
  380. *   INPUTS
  381. *    A pointer to the IORequest block whose resources are to be freed.
  382. *
  383. *   RESULT
  384. *    Frees the memory.  Returns (no error conditions shown)
  385. *
  386. *   EXAMPLE
  387. *    struct IORequest *myBlock;
  388. *    DeleteExtIO(myBlock,(sizeof(struct IOExtTD)));
  389. *        
  390. *    example shows that CreateExtIO had been used to create a trackdisk
  391. *    (extended) IO Request block.
  392. *
  393. *   SEE ALSO
  394. *    CreateExtIO
  395. *
  396. **************************************************************************/
  397.  
  398. DeleteExtIO(ioExt,size)
  399.     struct IORequest *ioExt;
  400.     LONG size;
  401. {
  402.     ioExt -> io_Message.mn_Node.ln_Type = 0xff;
  403.     ioExt -> io_Device = (struct Device *) -1;
  404.     ioExt -> io_Unit = (struct Unit *) -1;
  405.  
  406.     FreeMem (ioExt, size);
  407. }
  408.